Skip to content

Conversation

@minborg
Copy link
Contributor

@minborg minborg commented Oct 2, 2025

Implement JEP 526: Lazy Constants (Second Preview)

The lazy list/map implementations are broken out from ImmutableCollections to a separate class.

The old benchmarks are not moved/renamed to allow comparison with previous releases.

java.util.Optional is updated so that its field is annotated with @Stable. This is to allow Optional instances to be held in lazy constants and still provide constant folding.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change requires CSR request JDK-8366179 to be approved

Issues

  • JDK-8366178: Implement JEP 526: Lazy Constants (Second Preview) (Enhancement - P4)
  • JDK-8366179: Implement JEP 526: Lazy Constants (Second Preview) (CSR)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605
$ git checkout pull/27605

Update a local copy of the PR:
$ git checkout pull/27605
$ git pull https://git.openjdk.org/jdk.git pull/27605/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 27605

View PR using the GUI difftool:
$ git pr show -t 27605

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/27605.diff

Using Webrev

Link to Webrev Comment

* This is only possible if there is a direct reference from a {@code static final} field
* to a lazy constant or if there is a chain from a {@code static final} field -- via one
* or more <em>trusted fields</em> (i.e., {@code static final} fields,
* {@linkplain Record record} fields, lazy constants, lazy lists, lazy maps,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lazy constants and lazy lists/maps are not themselves "trusted final fields" (at least not yet), so not sure they belong here?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @Stable annotation makes fields with non‑null values into trusted fields when the class is loaded by a platform class loader.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be a chain: static final -> record component -> lazy list element -> record component, for example, and this would be a trusted chain. There are other constucts that could be in the chain as well and that are not mentioned (e.g. a List.of()) so perhaps we should do some change here. Easiest is to just remove the mention of lazy*.

@minborg
Copy link
Contributor Author

minborg commented Oct 24, 2025

After some discussion, we have concluded that we need to rework how toString() works for LazyConstant, lazy maps, and lists:

For LazyConstant

In order to align with other comput-later constructs like Future, we'd like to provide something like this:

java.lang.LazyConstant@5ed828d[computing function = $Lambda/0x00000ffe000d6550@4d3167f4]  // Uninitialized
java.lang.LazyConstant@4ad92aa[42] // Initialized

For lazy list, map, and all their derivatives (e.g., subList(), values())

There is a tension between the willingness to keep the toString() methods lazy during debugging and the compatibility with the existing List and Map implementations. It would be very surprising if a lazy list would output something different from a normal list for toString(). We think it is more important that lazy constructs are compatible with their corresponding eager constructs. Hence, we propose to make toString() trigger initialization of all elements/values.

* The returned lazy list strongly references its computing
* function used to compute elements only so long as there are uncomputed elements
* after which the computing function is not strongly referenced
* anymore and may be collected.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's okay to say that the computing function is kept strongly reachable until at least all elements have been computed. I'm less sure about the second part being normative text and wonder if it would be better to move that part to an implNote.

}

/**
* {@return a new lazily computed list with the provided {@code size}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A minor comment here is that "of the given size" might be a bit clearer than "with the provided size".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

9 participants